/*************************************************************************
	> File Name: 002.HZOJ223.cpp
	> Author: Maureen 
	> Mail: Maureen@qq.com 
	> Created Time: 一  2/22 11:57:48 2021
 ************************************************************************/

/**
 * 
题目描述:
 给定一个 𝑛 位数组和两种操作:
 操作1：数组中某个区间的所有数字加上一个值
 操作2：查询数组中某个区间的所有数字之和

输入:
第一行输入两个整数 𝑛,𝑚(1≤𝑛≤10000，3≤𝑚≤100000)，分别代表数组大小和操作数。
第二行包含 𝑛 个整数，代表数组中相应的数字，数字大小不会超过 𝑖𝑛𝑡 表示范围。
接下来 𝑚 行，每行三个或四个整数 𝑎,𝑏,𝑐,𝑑（𝑎∈[1,2]）
当 𝑎=1 时，接下来输入 𝑏,𝑐,𝑑，代表将数组 [𝑏,𝑐]区间内的数字加上 𝑑，(1≤𝑏,𝑐≤𝑛, 𝑑 𝑖𝑠 𝑖𝑛𝑡)，当 𝑏>𝑐 时，不做任何操作。
当 𝑎=2 时，接下来输入 𝑏,𝑐，输入代表询问 [𝑏,𝑐] 区间内的和值 ( 1≤𝑏,𝑐≤𝑛)，当 𝑏>𝑐 时，输出 0。

输出:
对于每个 𝑎=2 的操作，输出查询区间内数字的和值，答案不会超过64位整型（long long）的表示范围。
 * 
 **/

#include <iostream>
#include <cstdio>

using namespace std;

#define MAX_N 10000
struct {
    long long sum;
    long long tag;
} tree[MAX_N << 2];

int arr[MAX_N + 5];

void update(int ind) {
    tree[ind].sum = tree[ind << 1].sum + tree[ind << 1 | 1].sum;
    return ;
}

void buildSegmentTree(int ind, int l, int r) {
    if (l == r) {
        tree[ind].sum = arr[l];
        return ;
    }
    long long mid = (l + r) >> 1;
    buildSegmentTree(ind << 1, l, mid);
    buildSegmentTree(ind << 1 | 1, mid + 1, r);
    update(ind);
    return ;
}

void down(int ind, int l, int r) {
    if (tree[ind].tag) {
        long long val = tree[ind].tag;
        long long mid = (l + r) >> 1;
        tree[ind << 1].sum += (mid - l + 1) * val;
        tree[ind << 1].tag += val;
        tree[ind << 1 | 1].sum += (r - mid) * val;
        tree[ind << 1 | 1].tag += val;
        tree[ind].tag = 0;
    }
    return ;
}

void modify(int ind, int l, int r, int x, int y, int val) {
    if (x <= l && r <= y) {
        tree[ind].sum += val * (r - l + 1);
        tree[ind].tag += val;
        return ;
    }
    down(ind, l, r);
    long long mid = (l + r) >> 1;
    if (x <= mid) {
        modify(ind << 1, l, mid, x, y, val);
    }
    if (mid < y) {
        modify(ind << 1 | 1, mid + 1, r, x, y, val);
    }
    update(ind);
    return ;
}

long long query(int ind, int l, int r, int x, int y) {
    if (x <= l && r <= y) {
        return tree[ind].sum;
    }
    down(ind, l, r);
    long long mid = (l + r) >> 1;
    long long ans = 0;
    if (x <= mid) {
        ans += query(ind << 1, l, mid, x, y);
    }
    if (mid < y) {
        ans += query(ind << 1 | 1, mid + 1, r, x, y);
    }
    return ans;
}


int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%d", arr + i);
    }
    buildSegmentTree(1, 1, n);
    int a, b, c, d;
    for (int i = 0; i < m; i++) {
        scanf("%d", &a);
        switch (a){
            case 1: {
                scanf("%d%d%d", &b, &c, &d);
                modify(1, 1, n, b, c, d);
            } break;
            case 2: {
                scanf("%d%d", &b, &c);
                printf("%lld\n",query(1, 1, n, b, c));
            } break;
        }
    }
    return 0;
}
